package team.mai.antexpress.spring.controllers;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import team.mai.antexpress.dao.UserDAO;
import team.mai.antexpress.services.LoginService;
import team.mai.antexpress.spring.beans.LoginBean;
import team.mai.antexpress.utils.Validator;

import javax.servlet.http.HttpServletRequest;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import static org.springframework.web.bind.annotation.RequestMethod.GET;
import static org.springframework.web.bind.annotation.RequestMethod.POST;

@Controller
public class LoginController {

	private static final boolean TEST_MANDATORY_CAPTCHA_PASS = false;
	private static final boolean TEST_AUTO_LOGIN = false;

	public static final int CAPTCHA_ERROR = -1;
	public static final int INVALID_CREDENTIALS = -2;
	public static final int SUCCESS = 0;

	@Autowired
	LoginService loginService;
	@Autowired
	LoginBean loginBean;
	@Autowired
	HttpServletRequest request;
	@Autowired
	UserDAO userDAO;


	/**
	 * Request the login page
	 */
	@RequestMapping(value = "/login", method = GET)
	public String doGet(ModelMap map) {
		if (loginBean.isValidLogin()) {
//			map.addAttribute("isLoggedin", true);
			return redirectToAdminIndex(map);
		}
		return "login";
	}

	/**
	 * Request of logging in (POST)
	 */
	@Deprecated
	@RequestMapping(value = "/login", method = POST)
	public String doPost(String username, String password, String captcha, ModelMap map) {
		/*Test Scope Auto Login*/
		if (TEST_AUTO_LOGIN) {
			return redirectToAdminIndex(map);
		}
		/*Test Scope Auto Login*/
		loginBean.setUsername(username);
		loginBean.setPassword(password);
		loginBean.setCaptchaInput(captcha);
		if (loginService.verifyCaptcha(loginBean) || TEST_MANDATORY_CAPTCHA_PASS) {
			if (loginService.verifyLogin(loginBean)) {
				return redirectToAdminIndex(map);
			} else {
				map.addAttribute("loginStatus", INVALID_CREDENTIALS);
			}
		} else {
			map.addAttribute("loginStatus", CAPTCHA_ERROR);
		}
		return "login";
	}

	/**
	 * Ajax request POST of login
	 */
	@RequestMapping(value = "/login/ajax", method = POST)
	@ResponseBody
	public String doPost(String username, String password, String captcha) {
		/*Test Scope Auto Login*/
		if (TEST_AUTO_LOGIN) {
			loginBean.setValidLogin(true);
			request.getSession().setAttribute("login", true);
			return "{\"login\":\"ok\"}";
		}
		/*Test Scope Auto Login*/
		loginBean.setUsername(username);
		loginBean.setPassword(password);
		loginBean.setCaptchaInput(captcha);
		String response;
		if (loginService.verifyCaptcha(loginBean) || TEST_MANDATORY_CAPTCHA_PASS) {
			if (loginService.verifyLogin(loginBean)) {
				loginBean.setValidLogin(true);
				request.getSession().setAttribute("login", true);
				response = "{\"login\":\"ok\"}";
			} else {
				response = "{\"login\":\"invalid_credentials\"}";
			}
		} else {
			response = "{\"login\":\"captcha_error\"}";
		}
		return response;
	}

	/**
	 * request of checking if a user logged in
	 */
	@RequestMapping(value = "/logincheck", method = GET)
	@ResponseBody
	public String getLoginUser() {
		if (loginBean.isValidLogin()) {
			return "{\"login\":true,\"user\":\"" + loginBean.getUsername() + "\"}";
		} else {
			return "{\"login\":false}";
		}
	}

	/**
	 * request of getting a captcha image
	 */
	@RequestMapping(value = "/captcha", method = GET, produces = MediaType.IMAGE_JPEG_VALUE)
	@ResponseBody
	public byte[] getCaptcha() {
		try {
			return loginService.getCaptcha(loginBean);
		} catch (IOException e) {
			e.printStackTrace();
			return null;
		}
	}

	/**
	 * request of logging out
	 */
	@RequestMapping(value = "/logout", method = GET)
	public String logOut(ModelMap map) {
		loginBean.clear();
		//Do we need to invalidate the whole session?
		request.getSession().invalidate();
		map.addAttribute("url", "login");
		return "redirect";
	}

	@RequestMapping(value = "/changepassword", method = POST)
	@ResponseBody
	public Map<String, Object> changePassword(String password, String new_password) {
		Map<String, Object> json = new HashMap<>();
		if (userDAO.verifyLogin(loginBean.getUsername(), password)) {
			if (userDAO.changePassword(loginBean.getUsername(), new_password)) {
				json.put("status", "ok");
			} else {
				json.put("status", "error");
			}
		} else {
			json.put("status", "error");
		}
		return json;
	}

	private String redirectToAdminIndex(ModelMap map) {
		map.addAttribute("loginStatus", SUCCESS);
		map.addAttribute("url", "admin/index");
		loginBean.setValidLogin(true);
		request.getSession().setAttribute("login", true);
		return "redirect";
	}

	public int getCAPTCHAERROR() {
		return CAPTCHA_ERROR;
	}

	public int getINVALIDCREDENTIALS() {
		return INVALID_CREDENTIALS;
	}

	public int getSUCCESS() {
		return SUCCESS;
	}
}
